// 数据库连接池和Redis配置
import pg from 'pg';
import redis from 'redis';
import config from '../../config/config.js';

const { Pool } = pg;

// PostgreSQL连接池配置
const dbPool = new Pool({
  host: config.database.postgresql.host,
  port: config.database.postgresql.port,
  database: config.database.postgresql.name,
  user: config.database.postgresql.user,
  password: config.database.postgresql.password,
  max: config.database.postgresql.maxConnections,
  idleTimeoutMillis: config.database.postgresql.idleTimeout,
  connectionTimeoutMillis: config.database.postgresql.connectionTimeout,
  allowExitOnIdle: true,
  // 连接重试配置
  retry: {
    max: 3,
    delay: 1000
  }
});

// Redis客户端配置
const redisClient = redis.createClient({
  socket: {
    host: config.database.redis.host,
    port: config.database.redis.port
  },
  password: config.database.redis.password,
  database: config.database.redis.db
});

// 连接池事件监听
dbPool.on('connect', (client) => {
  console.log('✅ 数据库连接池: 新客户端连接');
});

dbPool.on('acquire', (client) => {
  console.log('🔗 数据库连接池: 客户端获取');
});

dbPool.on('remove', (client) => {
  console.log('❌ 数据库连接池: 客户端移除');
});

dbPool.on('error', (err, client) => {
  console.error('💥 数据库连接池错误:', err);
});

// Redis事件监听
redisClient.on('connect', () => {
  console.log('✅ Redis: 连接成功');
});

redisClient.on('error', (err) => {
  console.error('💥 Redis错误:', err);
});

redisClient.on('reconnecting', () => {
  console.log('🔄 Redis: 重新连接中...');
});

// 连接测试函数（带重试机制）
async function testDatabaseConnection(maxRetries = 3, retryDelay = 1000) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const result = await dbPool.query('SELECT NOW() as current_time');
      console.log('✅ 数据库连接测试成功:', result.rows[0].current_time);
      return true;
    } catch (error) {
      if (attempt < maxRetries) {
        console.warn(`⚠️ 数据库连接测试失败 (尝试 ${attempt}/${maxRetries}):`, error.message);
        console.log(`⏳ ${retryDelay/1000}秒后重试...`);
        await new Promise(resolve => setTimeout(resolve, retryDelay));
      } else {
        console.warn('⚠️ 数据库连接测试最终失败:', error.message);
        console.log('💡 服务器将在无数据库模式下运行');
        return false;
      }
    }
  }
}

async function testRedisConnection(maxRetries = 3, retryDelay = 1000) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      if (!redisClient.isOpen) {
        await redisClient.connect();
      }
      const pong = await redisClient.ping();
      console.log('✅ Redis连接测试成功:', pong);
      return true;
    } catch (error) {
      if (attempt < maxRetries) {
        console.warn(`⚠️ Redis连接测试失败 (尝试 ${attempt}/${maxRetries}):`, error.message);
        console.log(`⏳ ${retryDelay/1000}秒后重试...`);
        await new Promise(resolve => setTimeout(resolve, retryDelay));
      } else {
        console.warn('⚠️ Redis连接测试最终失败:', error.message);
        console.log('💡 服务器将在无缓存模式下运行');
        return false;
      }
    }
  }
}

// 优雅关闭函数
async function gracefulShutdown() {
  console.log('🛑 正在关闭数据库连接...');
  
  try {
    // 关闭Redis连接
    if (redisClient.isOpen) {
      await redisClient.quit();
      console.log('✅ Redis连接已关闭');
    }
    
    // 关闭数据库连接池
    await dbPool.end();
    console.log('✅ 数据库连接池已关闭');
    
  } catch (error) {
    console.error('❌ 关闭数据库连接时出错:', error);
  }
}

// 连接池统计信息
async function getPoolStats() {
  return {
    totalCount: dbPool.totalCount,
    idleCount: dbPool.idleCount,
    waitingCount: dbPool.waitingCount
  };
}

// 健康检查
async function healthCheck() {
  const dbHealth = await testDatabaseConnection();
  const redisHealth = await testRedisConnection();
  
  return {
    database: dbHealth ? 'healthy' : 'unhealthy',
    redis: redisHealth ? 'healthy' : 'unhealthy',
    timestamp: new Date().toISOString()
  };
}

export {
  dbPool,
  redisClient,
  testDatabaseConnection,
  testRedisConnection,
  gracefulShutdown,
  getPoolStats,
  healthCheck
};